// STL
#include <utility>              // std::pair<>, ::make_pair()

// Boost
#include <boost/math/distributions/normal.hpp> // boost::math::normal

// stats++
#include "statsxx/sampling.hpp" // statsxx::sampling::sample_size_m()


//
// DESC: Determine the sample size for simultaneously estimating the parameters of a multinomial population within a distance of the true values at a significance level.
//
// -----
//
// INPUT:
//
//     alpha : significance level
//
// -----
//
// OUTPUT:
//
//     d^2n  : d == distance, n == sample size
//     m     : the number of nonzero parameters, at which the "worst case" occurs for the given alpha
//
// -----
//
// NOTE: Returned is a "worst case" estimate, so (calculating) n should be rounded up.
//
// -----
//
// NOTE: See:
//
//     S. K. Thompson, "Sample Size for Estimating Multinomial Proportions," The American Statistician 41, 42--46 (1987)
//
// -----
//
inline std::pair<
                 double, // d2n
                 int     // m
                 > statsxx::sampling::sample_size_multinomial(
                                                              const double alpha
                                                              )
{
    double d2n;
    int    m = statsxx::sampling::sample_size_m(
                                                alpha
                                                );

    // CALCULATE d2n
    boost::math::normal dist;

    double z = boost::math::quantile(dist, (1. - alpha/(2*m)));

    d2n = z*z*(1./m)*(1. - 1./m);

    // RETURN
    return std::make_pair(
                          d2n,
                          m
                          );
}
